<?php

namespace app\ask\controller;

use mysqli;
use think\Controller;

class Messages extends Controller
{
    protected $BusinessModel;
    protected $PrivateMessagesModel;
    protected $messagePath = ROOT_PATH . DS . 'public' . DS . 'uploads' . DS . 'messages';
    protected $maxCount = 100; // 存在评论的最大数量

    public function __construct()
    {
        parent::__construct();

        $this->BusinessModel = model('Business.Business');
        $this->PrivateMessagesModel = model('PrivateMessages');

        /* $item = [
            'id' => 1,
            'type' => 'sender', // receiver
            'content' => '测试消息',
            'status' => 1,
            'create_time' => time(),
        ]; */

        if (!file_exists($this->messagePath)) {
            mkdir($this->messagePath, 0777, true);
        }
    }

    public function index()
    {
        $page = $this->request->param('page', 1, 'intval');
        $limit = $this->request->param('limit', 0, 'intval');
        $bus1id = $this->request->param('bus1id', 0, 'intval');
        $bus2id = $this->request->param('bus2id', 0, 'intval');

        $bus1id = intval($bus1id);
        $bus2id = intval($bus2id);

        if (!$limit) {
            $limit = 10;
        }

        // 分页偏移量
        $offset = ($page - 1) * $limit;

        $where = [
            'bus1id' => ['in', [$bus1id, $bus2id]],
            'bus2id' => ['in', [$bus1id, $bus2id]],
        ];

        if ($bus1id === $bus2id) {
            $this->error('不能和自己私信哦', null, 'back');
            exit;
        }

        $bus1 = $this->BusinessModel->find($bus1id);

        if (!$bus1) {
            $this->error('用户不存在01');
            exit;
        }

        $bus2 = $this->BusinessModel->find($bus2id);

        if (!$bus2) {
            $this->error('用户不存在02');
            exit;
        }

        $field = ['id', 'avatar_text', 'nickname'];

        $result = [
            'list' => [],
            'total' => 0,
            'bus1' => filter_property($bus1, $field),
            'bus2' => filter_property($bus2, $field),
        ];

        $room = $this->PrivateMessagesModel->where($where)->find();

        // 没有房间 id
        if (!$room) {
            $this->success('返回数据', null, $result);
            exit;
        }

        $result['id'] = $room['id'];

        $path = $room['data1'];
        $otherPath = $room['data2'];

        if ($bus1id !== $room['bus1id']) {
            $path = $room['data2'];
            $otherPath = $room['data1'];
        }

        $path = $path ? $this->messagePath . DS . $path : '';
        $otherPath = $otherPath ? $this->messagePath . DS . $otherPath : '';

        if (file_exists($path)) {
            try {
                $data = json_decode(file_get_contents($path));
                $data = array_reverse($data);

                $result['total'] = count($data);

                if ($offset < $result['total']) {
                    $start = - ($result['total'] - $offset);

                    // var_dump($result['total'] - $offset, 10);exit;
                    $result['list'] = array_reverse(array_slice($data, $start, $limit));
                }
            } catch (\Throwable $th) {
                $this->error('获取失败' . $th);
                exit;
            }
        }

        if (file_exists($otherPath)) {
            try {
                $other = json_decode(file_get_contents($otherPath));

                $co = 0;

                foreach ($other as &$item) {
                    if ($item->type === 'sender') {
                        $item->status = 1;
                        $co++;
                    }
                }

                if ($co > 0) {
                    try {
                        $other = json_encode($other, JSON_UNESCAPED_UNICODE);
                        file_put_contents($otherPath, $other);
                    } catch (\Throwable $th) {
                        $this->error('获取失败');
                        exit;
                    }
                }
            } catch (\Throwable $th) {
                $this->error('获取失败' . $th);
                exit;
            }
        }

        $this->success('返回数据', null, $result);
    }

    public function add()
    {
        $sender_id = $this->request->param('sender_id', 0, 'intval');
        $receiver_id = $this->request->param('receiver_id', 0, 'intval');
        $content =  $this->request->param('content', '', 'trim');

        $sender_id = intval($sender_id);
        $receiver_id = intval($receiver_id);

        if (!$content) {
            $this->error('私信内容不能为空');
            exit;
        }

        $senderBus = $this->BusinessModel->find($sender_id);

        if (!$senderBus) {
            $this->error('发送用户不存在');
            exit;
        }

        $receiverBus = $this->BusinessModel->find($receiver_id);

        if (!$receiverBus) {
            $this->error('接受用户不存在');
            exit;
        }

        $where = [
            'bus1id' => ['in', [$sender_id, $receiver_id]],
            'bus2id' => ['in', [$sender_id, $receiver_id]],
        ];

        $room = $this->PrivateMessagesModel->where($where)->find();

        $path1 = '';
        $path2 = '';
        $data1 = [];
        $data2 = [];

        $room_id = empty($room) ? 0 : $room['id'];

        // 没有查到房间号，新建一个房间
        if (empty($room)) {
            [$path1, $name1] = randomFileName($this->messagePath, 'txt');
            [$path2, $name2] = randomFileName($this->messagePath, 'txt');

            $data = [
                'bus1id' => $sender_id,
                'bus2id' => $receiver_id,
                'data1' => $name1,
                'data2' => $name2,
            ];

            $str = json_encode([]);

            if (file_put_contents($path1, $str) === false) {
                $this->error('发送失败01');
                exit;
            }

            if (file_put_contents($path2, $str) === false) {
                unlink($path1);
                $this->error('发送失败02');
                exit;
            }

            $res = $this->PrivateMessagesModel->save($data);

            if ($res === false) {
                $this->error('私信房间创建失败');
                exit;
            } else {
                $room_id = $this->PrivateMessagesModel->id;
            }

            $room = $data;
        } else {
            try {
                $path1 = $room['data1'] ? $this->messagePath . DS . $room['data1'] : '';
                if (file_exists($path1)) {
                    $data1 = json_decode(file_get_contents($path1));
                }
            } catch (\Throwable $th) {
                $this->error('发送失败03');
                exit;
            }

            try {
                $path2 = $room['data2'] ? $this->messagePath . DS . $room['data2'] : '';
                if (file_exists($path2)) {
                    $data2 = json_decode(file_get_contents($path2));
                }
            } catch (\Throwable $th) {
                $this->error('发送失败04');
                exit;
            }

            // 有房间号更新时间
            $data = [
                'id' => $room['id'],
                'updatetime' => time()
            ];

            $roomRes = $this->PrivateMessagesModel->isUpdate(true)->save($data);

            if ($roomRes === false) {
                $this->error('更新时间失败');
                exit;
            }
        }

        $sender = [
            'id' => uniqid(),
            'pid' => $room_id,
            'type' => 'sender', // receiver
            'content' => $content,
            'status' => 0,
            'create_time' => time(),
        ];

        // 复制一份
        $receiver = array_merge([], $sender);
        $receiver['type'] = 'receiver';

        if ($sender_id === $room['bus1id']) {
            $data1[] = $sender;
            $data2[] = $receiver;
        } else {
            $data1[] = $receiver;
            $data2[] = $sender;
        }

        // 保证数据长度在指定范围
        if (count($data1) > $this->maxCount) {
            array_shift($data1);
        }
        if (count($data1) > $this->maxCount) {
            array_shift($data1);
        }

        try {
            if (empty($room['data1'])) {
                [$path1, $name1] = randomFileName($this->messagePath, 'txt');
                $newData1 = [
                    'id' => $room_id,
                    'data1' => $name1,
                ];

                $res = $this->PrivateMessagesModel->isUpdate(true)->save($newData1);

                if ($res === false) {
                    $this->error('发送失败05');
                    exit;
                }
            }
            $data1 = json_encode($data1, JSON_UNESCAPED_UNICODE);
            file_put_contents($path1, $data1);

            if (empty($room['data2'])) {
                [$path2, $name2] = randomFileName($this->messagePath, 'txt');
                $newData2 = [
                    'id' => $room_id,
                    'data2' => $name2,
                ];

                $res = $this->PrivateMessagesModel->isUpdate(true)->save($newData2);

                if ($res === false) {
                    $this->error('发送失败06');
                    exit;
                }
            }
            $data2 = json_encode($data2, JSON_UNESCAPED_UNICODE);
            file_put_contents($path2, $data2);
        } catch (\Throwable $th) {
            $this->error('发送失败07');
            exit;
        }


        $this->success('私信发送成功', null, $sender);
        exit;
    }

    // 私信列表
    public function list()
    {
        $page = $this->request->param('page', 1, 'intval');
        $limit = $this->request->param('limit', 0, 'intval');
        $keyword = $this->request->param('keyword', '', 'trim');
        $busid = $this->request->param('busid', 0, 'intval');

        if (!$limit) {
            $limit = 10;
        }

        // 分页偏移量
        $offset = ($page - 1) * $limit;

        $business = $this->BusinessModel->find($busid);

        if (!$business) {
            $this->error('用户不存在');
            exit;
        }

        $where = "(( `bus1id` = $busid AND `data1` IS NOT NULL  ) OR ( `bus2id` = $busid AND `data2` IS NOT NULL ))";

        if ($keyword) {
            $where .= "AND (`bus1`.`nickname` LIKE '%$keyword%' OR `bus2`.`nickname` LIKE '%$keyword%')";
        }

        $total = $this->PrivateMessagesModel
            ->with(['bus1', 'bus2'])
            ->where($where)
            ->count();

        // echo $this->PrivateMessagesModel->getLastSql();exit;

        $list = $this->PrivateMessagesModel
            ->with(['bus1', 'bus2'])
            ->where($where)
            ->order('updatetime', 'desc')
            ->limit($offset, $limit)
            ->select();

        if (!empty($list)) {
            $field = ['id', 'avatar_text', 'nickname'];

            foreach ($list as &$item) {
                $item = $item->toArray();

                if (isset($item['bus1'])) {
                    $item['bus1'] = filter_property($item['bus1'], $field);
                }

                if (isset($item['bus2'])) {
                    $item['bus2'] = filter_property($item['bus2'], $field);
                }

                $selfPath = $item['data1'];
                $selfData = [];
                $otherPath = $item['data2'];
                $otherData = [];

                if ($item['bus1id'] !== intval($busid)) {
                    $selfPath = $item['data2'];
                    $otherPath = $item['data1'];
                }

                $selfPath = $selfPath ? $this->messagePath . DS . $selfPath : '';
                $otherPath = $selfPath ? $this->messagePath . DS . $otherPath : '';

                filter_property($item, ['data1', 'data1']);

                if (file_exists($selfPath)) {
                    $selfData = json_decode(file_get_contents($selfPath));
                }

                if (file_exists($otherPath)) {
                    $otherData = json_decode(file_get_contents($otherPath));
                }

                // 查询最新的记录
                $item['latest'] = array_slice($selfData, -1, 1);

                if (count($item['latest']) > 0) $item['latest']  = $item['latest'][0];

                // 未读数量
                $item['unread'] = 0;

                // myPrinf($otherData);exit;

                foreach ($otherData as $subitem) {
                    if ($subitem->type === 'sender' && $subitem->status === 0) {
                        $item['unread']++;
                    }
                }
            }
        }

        $this->success('获取私信列表成功', null, ['list' => $list ?? [], 'total' => $total]);
    }

    // 已读
    public function read()
    {
        $id = $this->request->param('id', 0, 'intval');
        $receiver_id = $this->request->param('receiver_id', 0, 'intval');

        $msg = $this->PrivateMessagesModel->find($id);

        if (!$msg) {
            $this->error('未找到记录');
            exit;
        }

        $path = $msg['data2'];
        $data = [];

        if (intval($receiver_id) === $msg['bus2id']) {
            $path = $msg['data1'];
        }

        $path = $path ? $this->messagePath . DS . $path : '';

        if (file_exists($path)) {
            try {
                $data = json_decode(file_get_contents($path));

                foreach ($data as &$item) {
                    if ($item->type === 'sender') {
                        $item->status = 1;
                    }
                }

                file_put_contents($path, json_encode($data));
            } catch (\Throwable $th) {
                $this->error('已读失败');
            }
        }

        $this->success('已读成功');
    }

    // 删除房间
    public function delroom()
    {
        $id = $this->request->param('id', 0, 'intval');
        $busid = $this->request->param('busid', 0, 'intval');

        $business = $this->BusinessModel->find($busid);

        if (!$business) {
            $this->error('用户不存在');
            exit;
        }

        $whereOr = [
            'bus1id' => $busid,
            'bus2id' => $busid,
        ];

        $room = $this->PrivateMessagesModel->where(['id' => $id])->whereOr($whereOr)->find();

        if (empty($room)) {
            $this->error('聊天室不存在');
            exit;
        }

        $data = [
            'id' => $id,
        ];

        if ($room['bus1id'] === intval($busid)) {
            $data['data1'] = null;
        } else {
            $data['data2'] = null;
        }

        $res = $this->PrivateMessagesModel->isUpdate(true)->save($data);

        if ($res === false) {
            $this->error('删除失败');
            exit;
        } else {
            $this->success('删除成功');
        }
    }

    // 删除
    public function del()
    {
        $id = $this->request->param('id', '', 'trim');
        $pid = $this->request->param('pid', 0, 'intval');
        $busid = $this->request->param('busid', 0, 'intval');

        $business = $this->BusinessModel->find($busid);

        if (!$business) {
            $this->error('用户不存在');
            exit;
        }

        $pmsg = $this->PrivateMessagesModel->find($pid);

        if (!$pmsg) {
            $this->error('私信聊天室不存在');
            exit;
        }

        $path1 = $pmsg['data1'];
        $path2 = $pmsg['data2'];

        $path1 = $path1 ? $this->messagePath . DS . $path1 : '';
        $path2 = $path2 ? $this->messagePath . DS . $path2 : '';

        if (file_exists($path1)) {
            $data1 = json_decode(file_get_contents($path1));
            $exist = false;

            foreach ($data1 as $k => $item) {
                if ($item->id === $id) {
                    $exist = true;

                    if ($item->create_time + (60 * 60 * 24) < time()) {
                        $this->error('超过 24 小时，不能修改了哦');
                        exit;
                    }

                    unset($data1[$k]);

                    break;
                }
            }

            if ($exist) {
                file_put_contents($path1, json_encode($data1));
            } else if ($business['id'] === $pmsg['bus1id']) {
                $this->error('私信记录不存在');
                exit;
            }
        }

        if (file_exists($path2)) {
            $data2 = json_decode(file_get_contents($path2));
            $exist = false;

            foreach ($data2 as $k => $item) {
                if ($item->id === $id) {
                    $exist = true;

                    if ($item->create_time + (60 * 60 * 24) < time()) {
                        $this->error('超过 24 小时，不能修改了哦');
                        exit;
                    }

                    unset($data2[$k]);

                    break;
                }
            }

            if ($exist) {
                file_put_contents($path2, json_encode($data2));
            } else if ($business['id'] === $pmsg['bus2id']) {
                $this->error('私信记录不存在');
                exit;
            }
        }

        $this->success('删除成功');
        exit;
    }
}
